package nlppatents.util;

import java.io.File;
import java.util.Arrays;
import java.util.Stack;

/**
 * Scans the 'txt' directory and returns Files/Patents in 
 * ascending order.  A numeric range (min to max) must be 
 * specified.
 * 
 * @author bresee
 *
 */
public class PatentTxtDirectoryScanner 
{
	public static final String DEFAULT_DIRECTORY = "../../txt";

	private class PathTrace
	{
		public PathTrace(File[] files, int index)
		{
			this.files = files;
			this.index = index;
		}
		File[] files;
		int index;
	}
	
	private int minRange;
	private int maxRange;
	private Stack<PathTrace> trace;
	public boolean incFrequency;
	
	public PatentTxtDirectoryScanner(int minRange, int maxRange)
	{
		this.minRange = minRange;
		this.maxRange = maxRange;
		this.incFrequency = false;
		
		File[] baseDir = listDirectory(DEFAULT_DIRECTORY);
		if(baseDir == null)
		{
			System.err.println("ERROR: \"txt\" directory not found!");
			System.exit(1);
		}
		
		trace = new Stack<PathTrace>();
		trace.push(new PathTrace(baseDir, 0));
	}
	
	public int getMinRange()
	{
		return minRange;
	}
	public int getMaxRange()
	{
		return maxRange;
	}
	
	/*private void popTrace()
	{
		System.out.println(" !!!!!!! POPTRACE CALLED !!!!!!!!!!!");
		trace.pop();
		if(trace.size() != 0)
		{
			//trace.peek().index++;
		}
	}*/
	
	public File nextFile()
	{
		if(trace.size() == 0)
			return null; // no more files left to check
		
		PathTrace dirs = trace.peek();
		
		if(dirs.index >= dirs.files.length)
		{
			// this directory is finished, go up the ladder
			trace.pop();
			return nextFile();
		}
		
		File f = dirs.files[dirs.index];
		int fileNum = getFilenameValue(f.getName());
		
		while((fileNum < 0) || ((fileNum < minRange) && !f.isDirectory()))
		{
			dirs.index++;
			if(dirs.index >= dirs.files.length)
			{
				trace.pop();
				return nextFile();
			}
			
			f = dirs.files[dirs.index];
			//System.out.println("Skipped, now on " + f.getName() + ", fileNum=" + fileNum + ", minRange=" + minRange);
			fileNum = getFilenameValue(f.getName());
		}
		
		// check for a non-numeric filename OR filenum that is smaller than minRange
		/*if((fileNum < 0) || ((fileNum < minRange) && !f.isDirectory()))
		{
			dirs.index++;
			return nextFile();
		}*/
		
		// see whether we have found the last patent we will process
		if(fileNum > maxRange)
		{
			return null;
		}
		
		// ok, file is within our valid range; see whether it's a directory
		if(f.isDirectory())
		{
			File[] nextFiles = listDirectory(f.getPath());
			if(nextFiles == null)
			{
				System.err.println("ERROR:  Problem recursing into subdirectory \"" + f.getPath() + "\"");
				System.exit(1);
			}
			// prep for next call
			dirs.index++;
			// recurse into subdirectory
			trace.push(new PathTrace(nextFiles, 0));
			return nextFile();
		}
		
		// prep for next call
		dirs.index++;
		// file is in range and is a File (not directory) so return it
		return f;
	}
	
	public Patent nextPatent()
	{
		File f = nextFile();
		if(f == null)
			return null;
		
		Patent p = Patent.readPatent(f.getPath(), incFrequency);
		// this definitely happens; lots of 0-length patents
		while(p == null)
		{
			System.err.println("WARNING:  Skipped empty file " + f.getName());
			f = nextFile();
			if(f == null)
				return null;
			p = Patent.readPatent(f.getPath(), incFrequency);
		}
		
		return p;
	}
	
	public static File[] listDirectory(String path)
	{
		File dir = new File(path);
		File[] files = dir.listFiles();
		if(files == null)
			return null;
		
		Arrays.sort(files);
		
		return files;
	}
	
	public static int getFilenameValue(String filename)
	{
		final byte zero = 48;
		final byte nine = 57;
		
		byte[] bytes = filename.getBytes();
		int offset = 0;
		
		while((offset < bytes.length) && (bytes[offset] >= zero) && (bytes[offset] <= nine))
			offset++;
		
		if(offset == 0)
			return -1;
		
		return Integer.parseInt(filename.substring(0, offset));
	}
	
	public static void main(String args[])
	{
		POS.init();
		DictWord.init();
		POSWord.init();
		
		PatentTxtDirectoryScanner scanner = new PatentTxtDirectoryScanner(7005000, 7010010);
		Patent p = null;
		
		System.out.println("====== STARTING ======");
		while((p = scanner.nextPatent()) != null)
		{
			System.out.println(p.number);
		}
		System.out.println("====== END ======");
		
		System.out.println("STATS:");
		System.out.println("  Number of DictWords:" + DictWord.dictionary.size());
		System.out.println("  Number of POSWords:" + POSWord.words.size());
	}
}
